package net.xxcl.kygl.controller;

import jxl.Cell;
import jxl.Sheet;
import jxl.Workbook;
import net.xxcl.kygl.pojo.*;
import net.xxcl.kygl.service.LoginService;
import net.xxcl.kygl.service.MenuService;
import net.xxcl.kygl.service.UserService;
import net.xxcl.kygl.util.DigestUtils;
import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.PrintWriter;
import java.util.*;

/**
 * User: 夏汛
 * Date: 11-12-1
 * Time: 上午11:46
 */
@Controller
@RequestMapping("/user")
public class UserController {
    @Autowired
    private UserService userService;
    @Autowired
    private LoginService loginService;
    @Autowired
    private MenuService menuService;

    /**
     * 登录验证
     * @param name
     * @param password
     * @param request
     * @param response
     * @return
     */
    @RequestMapping(value = "/login",method= RequestMethod.POST)
    public String loginCheck(@RequestParam("name") String name, @RequestParam("password") String password,
                             @RequestParam("kaptcha") String kaptcha, HttpServletRequest request,HttpServletResponse response){
        try{
            String kaptchaExpected = (String)request.getSession()
                    .getAttribute(com.google.code.kaptcha.Constants.KAPTCHA_SESSION_KEY);
            if (kaptcha == null || !kaptcha.equalsIgnoreCase(kaptchaExpected))
            {
                request.setAttribute("message","验证码错误");
                request.getSession().removeAttribute(com.google.code.kaptcha.Constants.KAPTCHA_SESSION_KEY);
                return "forward:/index.jsp";
            }
            int userid = userService.login(name,password);
            if(userid>0){
                User user = userService.selectByPrimaryKey(userid);
                List<Integer> roles = userService.getRoleIdsByUserId(user.getId());
                HttpSession session = request.getSession();
                session.setAttribute("user",user);
                session.setAttribute("roles",roles);
                return "redirect:/user.jsp";
            }
        } catch (Exception e){
            e.printStackTrace();
            request.setAttribute("message","数据库连接错误！");
            return "forward:/index.jsp";
        }
        request.setAttribute("message","用户名或者密码错误！");
        return "forward:/index.jsp";
    }

    /**
     * 获取用户菜单，根据父菜单id获取
     * @param request
     * @param response
     * @return
     */
    @RequestMapping(value="/menus",method= RequestMethod.POST)
    public @ResponseBody Map<String,Object> getMenus(@RequestParam(value = "parentId",required = false) Integer parentId,
                                HttpServletRequest request,HttpServletResponse response){
        Map<String,Object> responseMap = new HashMap<String, Object>();
        List<Integer> roles = (List<Integer>)request.getSession().getAttribute("roles");
        if(parentId == null){
            parentId = 0;
        }
        Object t = menuService.getMainMenuListByRoles(roles,parentId);
        responseMap.put("key",t);
        return responseMap;
    }

    /**
     * 获取用户列表
     * @param start
     * @param limit
     * @param name
     * @param username
     * @param deptids
     * @param roleid
     * @param subjectid
     * @return
     */
    @RequestMapping(value = "/list")
    public @ResponseBody Map<String,Object> list(@RequestParam(value = "start",required = false) Integer start,
                                                     @RequestParam(value = "limit",required = false) Integer limit,
                                                     @RequestParam(value = "loginname",required = false) String name,
                                                     @RequestParam(value = "username",required = false) String username,
                                                     @RequestParam(value = "deptids",required = false) String deptids,
                                                     @RequestParam(value = "roleid",required = false) Integer roleid,
                                                     @RequestParam(value = "subjectid",required = false) Integer subjectid){
        Map<String,Object> responseMap = new HashMap<String, Object>();
        Criteria criteria = new Criteria();
        criteria.put("isusing",1);
        criteria.put("iscolleague",1);
        //加上查询条件
        if(!(name==null || name.equals(""))) criteria.put("blurredName","%"+name+"%");
        if(!(username==null || username.equals(""))) criteria.put("blurredUsername","%"+username+"%");
        if(!(deptids==null || deptids.equals(""))){
            String[] str = deptids.split(",");
            List<String> deptList = new ArrayList<String>();
            for(String s:str){
                deptList.add(s);
            }
            criteria.put("deptids",deptList);
        }
        if(subjectid!=null){
            criteria.put("subjectid",subjectid);
        }
        if(roleid!=null){
            criteria.put("roleid",roleid);
        }
        int total = userService.countByExample(criteria);
        if(start!=null && limit!=null){
            criteria.setMysqlOffset(start);
            criteria.setMysqlLength(limit);
        }
        criteria.setOrderByClause("t_login.name");
        List<User> list = userService.selectByExample(criteria);
        for(User user:list){
            List<Role> roles = userService.getRolesByUserId(user.getId());
            String roleIds = "";
            String roleNames = "";
            for (Role role:roles){
                roleIds += role.getId()+",";
                roleNames += role.getName()+",";
            }
            if(roles.size()>0){
                user.setRoleIds(roleIds.substring(0,roleIds.length()-1));
                user.setRoleNames(roleNames.substring(0,roleNames.length()-1));
            }
        }
        responseMap.put("total",total);
        responseMap.put("rows",list);
        return responseMap;
    }

    /**
     * 根据部门id列出部门所有人员
     * @param deptid
     * @return
     */
    @RequestMapping(value = "/listUserByDeptid",method= RequestMethod.POST)
    public @ResponseBody Map<String,Object> list(@RequestParam("deptid") String deptid){
        Map<String,Object> responseMap = new HashMap<String, Object>();
        Criteria criteria = new Criteria();
        criteria.put("isusing",1);
        criteria.put("iscolleague",1);
        //加上查询条件
        criteria.put("deptid",deptid);
        int total = userService.countByExample(criteria);
        List<User> list = userService.selectByExample(criteria);
        responseMap.put("total",total);
        responseMap.put("rows",list);
        return responseMap;
    }

    /**
     * 根据项目id列出项目所有人员
     * @param projectid
     * @return
     */
    @RequestMapping(value = "/getUsersForProject",method= RequestMethod.POST)
    public @ResponseBody Map<String,Object> getUsersForProject(@RequestParam("projectid") Integer projectid){
        Map<String,Object> responseMap = new HashMap<String, Object>();
        Criteria criteria = new Criteria();
        criteria.put("projectid",projectid);
        criteria.setOrderByClause("t_user_project.rank");
        List<User> list = userService.selectByExample(criteria);
        responseMap.put("rows",list);
        return responseMap;
    }

    /**
     * 根据id查找用户
     * @param id
     * @return
     */
    @RequestMapping(value = "/selectById",method= RequestMethod.POST)
    public @ResponseBody Map<String,Object> list(@RequestParam("id") Integer id){
        Map<String,Object> responseMap = new HashMap<String, Object>();
        responseMap.put("user",userService.selectByPrimaryKey(id));
        return responseMap;
    }

    /**
     * 校外用户，返回用户id
     * @param user
     * @return
     */
    @RequestMapping(value = "/saveOutSchoolUser",method= RequestMethod.POST)
    public @ResponseBody Map<String,Object> saveOutSchoolUser(@ModelAttribute("user") User user){
        Map<String,Object> responseMap = new HashMap<String,Object>();
        try{
            user.setIscolleague(false);
            responseMap.put("id",userService.insertSelective(user));
            //注意，必须加下边这句，ext表单的success回调才能执行
            responseMap.put("success",true);
        } catch (Exception e){
            e.printStackTrace();
            responseMap.put("info", e.getClass()+":"+e.getMessage());
        }
        return responseMap;
    }

    /**
     * 新增或编辑
     * @param user
     * @return
     */
    @RequestMapping(value="/save",method= RequestMethod.POST)
    public @ResponseBody Map<String,Object> saveOrUpdate(@ModelAttribute("user") User user,
                                                         @RequestParam("name") String name){
        Map<String,Object> responseMap = new HashMap<String,Object>();
        try{
            Criteria criteria = new Criteria();
            criteria.put("name",name);
            //新增用户
            if(user.getId()==null){
                //判断登录名是否已存在
                if(loginService.isNameExist(criteria)){
                    responseMap.put("info", "登录名已经存在！");
                    return responseMap;
                }
                userService.addUser(user, name, "888888");
                responseMap.put("method", "Create");
                responseMap.put("success", "true");
                responseMap.put("info", "新增成功，初始密码为888888！");
            }
            //编辑用户
            else {
                //编辑用户判断登录名是否已存在，查询数据库时需排除该用户id所在的记录
                criteria.put("userid",user.getId());
                if(loginService.isNameExist(criteria)){
                    responseMap.put("info", "登录名已经存在！");
                    return responseMap;
                }
                userService.updateUser(user,name);
                responseMap.put("success", "true");
                responseMap.put("info", "编辑成功！");
            }
        } catch (Exception e){
            e.printStackTrace();
            responseMap.put("info", e.getClass()+":"+e.getMessage());
        }
        return responseMap;
    }

    /**
     * 修改密码
     * @param password
     * @param request
     * @param response
     * @return
     */
    @RequestMapping(value="/changePwd",method= RequestMethod.POST)
    public @ResponseBody Map<String,Object> changePwd(
            @RequestParam("oldpassword") String oldpassword,@RequestParam("password") String password,
            HttpServletRequest request,HttpServletResponse response){
        Map<String,Object> responseMap = new HashMap<String,Object>();
        try{
            User user = (User)request.getSession().getAttribute("user");
            Criteria criteria = new Criteria();
            criteria.put("userid",user.getId());
            List<Login> logins = loginService.selectByExample(criteria);
            Login login = logins.get(0);
            if(!DigestUtils.encodeSHA512Hex(oldpassword.getBytes()).equals(login.getPassword())){
                responseMap.put("info", "旧密码不正确");
                return responseMap;
            } else {
                login.setPassword(DigestUtils.encodeSHA512Hex(password.getBytes()));
                loginService.updateByPrimaryKeySelective(login);
                responseMap.put("success", "true");
                responseMap.put("info", "密码成功修改！");
            }

        } catch (Exception e){
            e.printStackTrace();
            responseMap.put("info", "密码修改失败");
        }
        return responseMap;
    }

    /**
     * 删除
     * @param ids
     * @return
     */
    @RequestMapping(value="/remove",method=RequestMethod.POST)
    public @ResponseBody Map<String,Object> remove(@RequestParam("ids") String ids){
        Map<String,Object> responseMap = new HashMap<String,Object>();
        try {
            userService.deleteUser(ids);
            responseMap.put("success", "true");
            responseMap.put("info", "删除成功！");
            return responseMap;
        }catch(Exception e) {
            e.printStackTrace();
            responseMap.put("info", e.getClass()+":"+e.getMessage());
            return responseMap;
        }
    }

    /**
     * 重置密码
     * @param ids
     * @return
     */
    @RequestMapping(value="/resetPass",method=RequestMethod.POST)
    public @ResponseBody Map<String,Object> resetPass(@RequestParam("ids") String ids){
        Map<String,Object> responseMap = new HashMap<String,Object>();
        try {
            userService.resetPass(ids,"888888");
            responseMap.put("success", "true");
            responseMap.put("info", "选中用户密码重置为888888！");
            return responseMap;
        }catch(Exception e) {
            e.printStackTrace();
            responseMap.put("info", e.getClass()+":"+e.getMessage());
            return responseMap;
        }
    }

    /**
     * 关联角色
     * @param roleids
     * @param userids
     * @return
     */
    @RequestMapping(value="/glRole",method=RequestMethod.POST)
    public @ResponseBody Map<String,Object> glRole(@RequestParam("roleids") String roleids,
                                                   @RequestParam("userids") String userids){
        Map<String,Object> responseMap = new HashMap<String,Object>();
        try {
            userService.glRole(roleids,userids);
            responseMap.put("success", "true");
            responseMap.put("info", "用户角色已修改成功");
            return responseMap;
        }catch(Exception e) {
            e.printStackTrace();
            responseMap.put("info", e.getClass()+":"+e.getMessage());
            return responseMap;
        }
    }

    @RequestMapping(value="/import",method=RequestMethod.POST)
    public void importFromExcel(MultipartHttpServletRequest request,HttpServletResponse response){
        MultipartFile file = request.getFile("file");
        response.setContentType("text/html");
        response.setCharacterEncoding("utf-8");
        PrintWriter out = null;
        try {
            out = response.getWriter();
            if(!file.isEmpty()){
                String fileHz = "";
                //如果文件类型是excel 2003，后缀名设置为.xls，excel 2007则设置为.xlsx
                if(file.getContentType().equals("application/vnd.ms-excel")){
                    fileHz = ".xls";
                } else {
                    out.print("{'info':'暂只能支持excel 2003格式的文件'}");
                    return;
                }

                String filePath = request.getSession().getServletContext().getRealPath("/");
                String fileName = UUID.randomUUID() + fileHz;

                File dirPath = new File(filePath);
                if (!dirPath.exists()) {
                    dirPath.mkdirs();
                }
                String realPath = filePath+File.separator+"temp"+File.separator+fileName;
                File saveFile = new File(realPath);
                FileUtils.writeByteArrayToFile(saveFile, file.getBytes());
                out.print("{'info':'"+importToDB(realPath)+"'}");
            }
        } catch(Exception e) {
            e.printStackTrace();
            out.print("{'info':'导入失败！'");
        } finally {
            if(out!=null){
                out.flush();
                out.close();
            }
        }
        return;
    }

    private String importToDB(String fileToBeRead){
        String message = "";    //返回的信息
        int totalSuccess = 0;   //导入成功条数
        int total = 0;          //总条数
        String errorLine = "";  //错误的行号
        try{
            //创建对工作薄的引用
            Workbook book = Workbook.getWorkbook(new File(fileToBeRead));
            //创建对第一张工作表的引用
            Sheet sheet = book.getSheet(0);
            //获取有效行数（可能中间有空行，因此不等于总条数）
            int rowNumber = sheet.getRows();
            //i=1开始循环，默认第一行为标题行，不读取
            for(int i=1;i<rowNumber;i++){
                //获取行数据
                Cell[] cells = sheet.getRow(i);
                //第一列为设置的必选，如果该列没有内容，那么认为该行是空行
                if(cells[0].getContents()==null || cells[0].getContents().equals("")){
                    continue;
                }
                total += 1;
                try{
                    userService.saveExcelRow(cells);
                    totalSuccess += 1;
                } catch (RuntimeException e){
                    //errorLine += ","+(total+1);
                    message += "第"+(total+1)+"行导入失败，原因：<br />" + e.getMessage() + "<br />";
                }
            }
        } catch (Exception e){
            e.printStackTrace();
        }
        message = "导入成功"+totalSuccess+"条记录！<br />" + message;
//        if(!errorLine.equals("")){
//            //用substring(1)是为了去掉最前边的逗号
//            message += "导入失败"+(total-totalSuccess)+"条记录!<br />失败的行："+errorLine.substring(1);
//        }
        return message;
    }
}
